﻿/*
* Copyright (c) 2010-2012 Tesla Engine Group
* 
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* 
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* 
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

using System;
using Tesla.Collections;
using Tesla.Content;
using Tesla.Core;
using Tesla.Graphics.Implementation;

namespace Tesla.Graphics {
    /// <summary>
    /// Interface for a render system, which provides all the means with communicating to the graphics device and
    /// creating concrete implementations for graphics objects.
    /// </summary>
    public interface IRenderSystemProvider : IDisposable {

        /// <summary>
        /// Gets a description of the render system's platform.
        /// </summary>
        String Platform {
            get;
        }

        /// <summary>
        /// Gets the renderer.
        /// </summary>
        IRenderer Renderer {
            get;
        }

        /// <summary>
        /// Gets the default graphics adapter.
        /// </summary>
        IGraphicsAdapter DefaultAdapter {
            get;
        }

        /// <summary>
        /// Gets all the adapters supported by ths system.
        /// </summary>
        ReadOnlyList<IGraphicsAdapter> Adapters {
            get;
        }

        /// <summary>
        /// Gets the default content manager which provides access to platform-specific content.
        /// </summary>
        ContentManager DefaultContent {
            get;
        }

        #region SwapChain

        /// <summary>
        /// Creates a new swap chain implementation.
        /// </summary>
        /// <param name="windowHandle">Pointer to the window</param>
        /// <param name="presentParams">Presentation parameters</param>
        /// <returns>Swap chain implemented</returns>
        SwapChainImplementation CreateSwapChainImplementation(IntPtr windowHandle, PresentationParameters presentParams);

        #endregion

        #region RenderStates

        /// <summary>
        /// Creates a new blend state implementation.
        /// </summary>
        /// <returns>Blend state implementation</returns>
        BlendStateImplementation CreateBlendStateImplementation();

        /// <summary>
        /// Creates a new depth stencil state implementation.
        /// </summary>
        /// <returns>Depth stencil implementation</returns>
        DepthStencilStateImplementation CreateDepthStencilStateImplementation();

        /// <summary>
        /// Creates a new sampler state implementation.
        /// </summary>
        /// <returns>Sampler state implementation</returns>
        SamplerStateImplementation CreateSamplerStateImplementation();

        /// <summary>
        /// Creates a new rasterizer state implementation.
        /// </summary>
        /// <returns>Rasterizer state implementation</returns>
        RasterizerStateImplementation CreateRasterizerStateImplementation();

        #endregion

        #region VertexBuffer

        /// <summary>
        /// Creates a new vertex buffer implementation.
        /// </summary>
        /// <param name="declaration">Declaration to use</param>
        /// <param name="vertexCount">Number of vertices</param>
        /// <param name="usage">Resource usage</param>
        /// <returns>Vertex buffer implementation</returns>
        VertexBufferImplementation CreateVertexBufferImplementation(VertexDeclaration declaration, int vertexCount, ResourceUsage usage);

        /// <summary>
        /// Creates a new vertex buffer implementation populated with the specified interleaved buffer.
        /// </summary>
        /// <param name="declaration">Declaration to use</param>
        /// <param name="usage">Resource usage</param>
        /// <param name="data">Interleaved DataBuffer to copy from. Stride must match the vertex declaration.</param>
        /// <returns>Vertex buffer implementation</returns>
        VertexBufferImplementation CreateVertexBufferImplementation(VertexDeclaration declaration, ResourceUsage usage, DataBuffer data);

        /// <summary>
        /// Creates a new vertex buffer implementation populated with the array of data buffers, one buffer for each vertex element.
        /// These must match up with the defined vertex declaration elements and be of the same number.
        /// </summary>
        /// <param name="declaration">Declaration to use</param>
        /// <param name="usage">Resource usage</param>
        /// <param name="data">DataBuffers to copy from, one for each vertex element. Total stride and size of each element must match the vertex declaration</param>
        /// <returns></returns>
        VertexBufferImplementation CreateVertexBufferImplementation(VertexDeclaration declaration, ResourceUsage usage, params DataBuffer[] data);

        #endregion

        #region IndexBuffer

        /// <summary>
        /// Creates a new index buffer implementation.
        /// </summary>
        /// <param name="format">Index format, 16 or 32 bits.</param>
        /// <param name="indexCount">Number of indices</param>
        /// <param name="usage">Resource usage</param>
        /// <returns>Index buffer implementation</returns>
        IndexBufferImplementation CreateIndexBufferImplementation(IndexFormat format, int indexCount, ResourceUsage usage);

        /// <summary>
        /// Creates a new index buffer implementation populated with the specified Int32 data.
        /// </summary>
        /// <param name="data">DataBuffer to copy from</param>
        /// <param name="usage">Resource usage</param>
        /// <returns>Index buffer implementation</returns>
        IndexBufferImplementation CreateIndexBufferImplementation(DataBuffer<int> data, ResourceUsage usage);
        
        /// <summary>
        /// Creates a new index buffer implementation popualted with the specified Int16 data.
        /// </summary>
        /// <param name="data">DataBuffer to copy from</param>
        /// <param name="usage">Resource usage</param>
        /// <returns>Index buffer implementation</returns>
        IndexBufferImplementation CreateIndexBufferImplementation(DataBuffer<short> data, ResourceUsage usage);

        #endregion

        #region Effect

        /// <summary>
        /// Creates a new effect implementation.
        /// </summary>
        /// <param name="shaderByteCode">Compiled shader byte code.</param>
        /// <returns>Effect implementation</returns>
        EffectImplementation CreateEffectImplementation(byte[] shaderByteCode);

        #endregion

        #region Texture

        /// <summary>
        /// Creates a new texture 1D implementation.
        /// </summary>
        /// <param name="width">Width of the texture</param>
        /// <param name="genMipmap">True if mipmaps should be generated</param>
        /// <param name="format">Surface format</param>
        /// <param name="data">DataBuffer to populate from, if null an empty texture and miplevels are generated.</param>
        /// <returns>Texture 1D implementation</returns>
        Texture1DImplementation CreateTexture1DImplementation(int width, bool genMipmap, SurfaceFormat format, DataBuffer data);

        /// <summary>
        /// Creates a new texture 2D implementation.
        /// </summary>
        /// <param name="width">Width of the texture</param>
        /// <param name="height">Height of the texture</param>
        /// <param name="genMipmap">True if mipmaps should be generated</param>
        /// <param name="format">Surface format</param>
        /// <param name="data">DataBuffer to populate from, if null an empty texture is generated.</param>
        /// <returns>Texture 2D implementation</returns>
        Texture2DImplementation CreateTexture2DImplementation(int width, int height, bool genMipmap, SurfaceFormat format, DataBuffer data);

        /// <summary>
        /// Creates a new texture 3D implementation.
        /// </summary>
        /// <param name="width">Width of the texture</param>
        /// <param name="height">Height of the texture</param>
        /// <param name="depth">Depth of the texture</param>
        /// <param name="genMipmap">True if mipmaps should be generated</param>
        /// <param name="format">Surface format</param>
        /// <param name="data">DataBuffer to populate from, if null an empty texture is generated.</param>
        /// <returns>Texture 3D implementation</returns>
        Texture3DImplementation CreateTexture3DImplementation(int width, int height, int depth, bool genMipmap, SurfaceFormat format, DataBuffer data);

        /// <summary>
        /// Creates a new texture cube implementation.
        /// </summary>
        /// <param name="size">Size (width/height) of the cube texture</param>
        /// <param name="genMipmap">True if mipmaps should be generated</param>
        /// <param name="format">Surface format</param>
        /// <param name="data">DataBuffer to populate from, if null an empty texture is generated.</param>
        /// <returns>Texture cube implementation</returns>
        TextureCubeImplementation CreateTextureCubeImplementation(int size, bool genMipmap, SurfaceFormat format, DataBuffer[] data);
        #endregion

        #region RenderTarget

        /// <summary>
        /// Creates a new render target 2D implementation. All render targets are themselves textures.
        /// </summary>
        /// <param name="width">Width of the target</param>
        /// <param name="height">Height of the target</param>
        /// <param name="genMipMaps">True if mipmaps should be generated</param>
        /// <param name="format">Surface format</param>
        /// <param name="depthFormat">Depth format. For Multi-RenderTarget (MRT) usage, the depth buffer from the first render target
        /// set on the device will be used for all proceeding targets assigned.</param>
        /// <param name="multiSampleCount">Multisample count</param>
        /// <param name="usage">Render target usage</param>
        /// <returns>Render target 2D implementation</returns>
        Texture2DImplementation CreateRenderTarget2DImplementation(int width, int height, bool genMipMaps, SurfaceFormat format, DepthFormat depthFormat, int multiSampleCount, RenderTargetUsage usage);

        /// <summary>
        /// Creates a new render target Cube implementation. All render targets are themselves textures.
        /// </summary>
        /// <param name="size">Size of the target (width/height are the same)</param>
        /// <param name="genMipMaps">True if mipmaps should be generated</param>
        /// <param name="format">Surface format</param>
        /// <param name="depthFormat">Depth format. For Multi-RenderTarget (MRT) usage, the depth buffer from the first render target
        /// set on the device will be used for all proceeding targets assigned.</param>
        /// <param name="multiSampleCount">Multisample count</param>
        /// <param name="usage">Render target usage</param>
        /// <returns>Render target Cube implementation</returns>
        TextureCubeImplementation CreateRenderTargetCubeImplementation(int size, bool genMipMaps, SurfaceFormat format, DepthFormat depthFormat, int multiSampleCount, RenderTargetUsage usage);
        
        #endregion
    }
}
